#include "s3c2416.h"
#include "uart.h"
#include "Exception.h"
#include <stdio.h>


#define UART_RX_FIFO_CNT 64

//extern void Uart_SendByte(unsigned char data);

static void Uart0_IRQ()
{
	volatile char TempChar;
	unsigned char Count;
	unsigned int i;
	
	if (rSUBSRCPND & 0x1)
	{
		// Receive Interrupt
		if (rUFSTAT0 & 0x40)
		{
			  for (i=0; i<UART_RX_FIFO_CNT; i++) 
				{  
					 TempChar = (unsigned char)rURXH0;
						 Uart_SendByte(TempChar);
				}
				 
		}
		else
		{
			 Count = rUFSTAT0 & 0x3f; 
			 for (i=0; i<Count; i++) 
			 {  
					 TempChar = (unsigned char)rURXH0;
					 Uart_SendByte(TempChar);
			 }
		}
		
		rSUBSRCPND |= 0x1;  
	}
//	if (rSUBSRCPND & (0x1<<1)) {
//		// Transmit Interrupt
//		Count = (rUFSTAT0>>8) & 0x3f; // FIFO???????
//		if (TxLen > (64-Count)) { // FIFO??64???
//	// ????????????,????64???FIFO,???FIFO??
//	// ??????FIFO?,??????????????
//			TxLen -= 64 - Count; // ???????????????
//			for (i=0; i<64-Count; i++) { // ???????FIFO?
//				rUTXH0 = *pTxData++;
//			}
//		} else if (TxLen > 0) { // ???????????FIFO?
//			for (i=0; i<TxLen; i++) { // ???????FIFO?			
//				rUTXH0 = *pTxData++;
//			}
//			TxLen = 0; // ????????
//		} else {
//			// ?????????????,??cpu??
//			TxLen = -1; // ????????	
//		// ?????,FIFO?,?????,????????????	
//			rINTSUBMSK |= (1 << 1);
//		}		
//		rSUBSRCPND |= (0x1<<1);	// ??Uart0 TX?????
//	}
	if (rSUBSRCPND & (0x1<<1)) 
	{  
		 rSUBSRCPND |= (0x1<<1);			
	}
	
	rSRCPND1 |= (0x1 << INT_UART0); // ??Uart0?????
	rINTPND1 |= (0x1 << INT_UART0);	// ??Uart0????
}

void Uart_SendByte(unsigned char data)
{
	while(!(rUTRSTAT0 & 0x2));
	WrUTXH0(data);
}

int fputc(int ch, FILE *f)
{
	 Uart_SendByte(ch);
	 return 0;
}

void Uart_Init()
{
	 
	rGPHCON &= ~((3<<0)|(3<<2));
	rGPHCON |= (2<<0)|(2<<2);	
	 
	rULCON0 = 0x3;
	 
	rUFCON0 = (0<<6) | (0<<4) | 0x7;
 
	rUMCON0 = 0;
	 
	rUCON0 = 0x5 | (1<<7) | (2<<10);
	 
	rUBRDIV0 = 66000000/(16*Baudrate)-1;
	rUDIVSLOT0 = 0x0888;
	 
	IRQ_Register(INT_UART0, Uart0_IRQ);
	 
	rINTMOD1 &= ~(1 << INT_UART0);

	rINTSUBMSK |= 0x7;
	rINTSUBMSK &= ~(1 << 0);	
	 
	rINTMSK1 &= ~(1 << INT_UART0);
}
